package {{ packageName }}.sample.infrastructure.secondary;

import {{ packageName }}.sample.domain.BeerId;
import {{ packageName }}.sample.domain.beer.Beer;
import {{ packageName }}.sample.domain.beer.Beers;
import {{ packageName }}.sample.domain.beer.BeersRepository;
import {{ packageName }}.shared.error.domain.Assert;
import org.springframework.data.cassandra.core.CassandraBatchOperations;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.stereotype.Repository;

import java.util.Optional;

import static {{ packageName }}.sample.domain.beer.BeerSellingState.NOT_SOLD;

@Repository
class SpringDataBeersRepository implements BeersRepository {

  private final CassandraOperations cassandraTemplate;
  private final CassandraBeerRepository beers;
  private final CassandraBeerCatalogRepository beersCatalog;

  public SpringDataBeersRepository(CassandraOperations cassandraTemplate, CassandraBeerRepository beers, CassandraBeerCatalogRepository beersCatalog) {
    this.cassandraTemplate = cassandraTemplate;
    this.beers = beers;
    this.beersCatalog = beersCatalog;
  }

  @Override
  public void save(Beer beer) {
    Assert.notNull("beer", beer);
    CassandraBatchOperations batchOps = cassandraTemplate.batchOps();

    batchOps.insert(BeerTable.from(beer));

    if (beer.sellingState() == NOT_SOLD) {
      batchOps.delete(BeerCatalogTable.from(beer));
    } else {
      batchOps.insert(BeerCatalogTable.from(beer));
    }

    batchOps.execute();
  }

  @Override
  public Beers catalog() {
    return new Beers(beersCatalog.findAll().stream().map(BeerCatalogTable::toDomain).toList());
  }

  @Override
  public Optional<Beer> get(BeerId beer) {
    Assert.notNull("beer", beer);

    return beers.findById(beer.get()).map(BeerTable::toDomain);
  }
}
